package ms.maplestory.boot.service;

import ms.maplestory.boot.client.User;
import ms.maplestory.boot.client.character.Char;
import ms.maplestory.boot.client.character.CharStat;
import ms.maplestory.boot.client.character.JobManager;
import ms.maplestory.boot.enums.JobType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import ms.maplestory.boot.repository.CharRepository;
import ms.maplestory.boot.service.helpers.CharHelper;
import ms.maplestory.boot.service.jobs.IJobService;
import ms.maplestory.boot.world.LoginServer;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


@Slf4j
@Service
@RequiredArgsConstructor
public class CharService extends JpaService<Char, Integer> {

    private final CharStatService charStatService;
    private final InventoryService inventoryService;
    private final AccountService accountService;

    @Override
    public CharRepository getRepository() {
        return (CharRepository) super.getRepository();
    }

    @Transactional
    public Char initChar(User user, String name, int curSelectedRace, short curSelectedSubJob, byte gender, int[] items) {
        JobType job = JobType.LoginJob.getLoginJobById(curSelectedRace).getBeginJob();
        Char chr = createChar(user, name, job.getId(), curSelectedRace, curSelectedSubJob, gender, items);
        inventoryService.initForCreateChar(chr, items);
        user.addChar(chr);
        CharStat charStat = chr.getStat();
        charStat.setCharId(chr.getId());
        charStat.setWorldId(user.getWorldId());
        charStatService.save(charStat);
        return chr;
    }

    @Transactional
    public Char createChar(User user, String name, int jobId, int curSelectedRace, short curSelectedSubJob, byte gender, int[] items) {
        Char chr = new Char();
        CharStat charStat = charStatService.createCharStat(name, jobId, gender, items[0], items[1], items[3], curSelectedRace, curSelectedSubJob);
        chr.setUser(user);
        chr.setStat(charStat);
        inventoryService.saveAll(CharHelper.getInventories(chr));
        save(chr);
        IJobService jobService = JobManager.getJobByIdAndChar(jobId, chr);
        if (jobService != null) {
            jobService.initCharCreationStats(chr);
        }
        return chr;
    }

    @Transactional
    public void logout(Char chr) {
        log.info("Logging out..." + chr.getStat().getName());
        chr.getField().removeChar(chr);
        chr.getAccount().setCurrentChr(null);
        if (!chr.isChangingChannel()) {
            chr.getClient().getChannelServerInstance().removeChar(chr);
            LoginServer.getInstance().removeAccount(chr.getAccount());
        }else{
            chr.getClient().setChr(null);
        }
       accountService.save(chr.getAccount());
    }
}
